﻿using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Data;
using System.Drawing.Design;
using System.Text;
using System.Web.UI;
using System.Web.UI.Design;
using Srvtools;
using System.Web.UI.WebControls;
using System.Web.Script.Serialization;
using System.Collections.Generic;
using System.Collections;

namespace AjaxTools
{
    [ParseChildren(true)]
    [PersistChildren(false)]
    [Designer(typeof(ExtGridDesigner), typeof(IDesigner))]
    public class AjaxGridView : AjaxBaseControl, IAjaxDataSource
    {
        public AjaxGridView()
        {
        }

        string _dataSourceId = "";
        string _expanderRowTemplate = "";
        string _edtPanId = "";
        string _queryPanId = "";
        bool _genRowNumberer = false;
        bool _allowExpandRow = true;
        bool _getServerText = true;
        ExtGridPagingSet _pagingSet = null;
        ExtGridStoreSet _storeSet = null;
        ExtGridGridSet _gridSet = null;
        ExtGridColumnCollection _columns;
        ExtGridToolItemCollection _toolItems;

        #region Properties
        [Category("Infolight")]
        [DefaultValue("")]
        [Editor(typeof(DataSourceEditor), typeof(UITypeEditor))]
        public string DataSourceID
        {
            get { return _dataSourceId; }
            set { _dataSourceId = value; }
        }

        [Category("Infolight")]
        [DefaultValue("")]
        public string ExpanderRowTemplateHtml
        {
            get { return _expanderRowTemplate; }
            set { _expanderRowTemplate = value; }
        }

        [Category("Infolight")]
        [DefaultValue("")]
        [Editor(typeof(ExtStaticStringEditor), typeof(UITypeEditor))]
        public string EditPanelID
        {
            get { return _edtPanId; }
            set { _edtPanId = value; }
        }

        [Category("Infolight")]
        [DefaultValue("")]
        [Editor(typeof(ExtStaticStringEditor), typeof(UITypeEditor))]
        public string QueryPanelID
        {
            get { return _queryPanId; }
            set { _queryPanId = value; }
        }

        [Category("Infolight")]
        [DefaultValue(false)]
        public bool GenRowNumberer
        {
            get { return _genRowNumberer; }
            set { _genRowNumberer = value; }
        }

        [Category("Infolight")]
        [DefaultValue(true)]
        public bool AllowExpandRow
        {
            get { return _allowExpandRow; }
            set { _allowExpandRow = value; }
        }

        [Category("Infolight")]
        [DefaultValue(true)]
        public bool GetServerText
        {
            get { return _getServerText; }
            set { _getServerText = value; }
        }

        [Category("Infolight")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [NotifyParentProperty(true)]
        public ExtGridStoreSet StoreSet
        {
            get
            {
                if (_storeSet == null)
                {
                    _storeSet = new ExtGridStoreSet(this);
                }
                return _storeSet;
            }
            set { _storeSet = value; }
        }

        [Category("Infolight")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [NotifyParentProperty(true)]
        public ExtGridPagingSet PagingSet
        {
            get
            {
                if (_pagingSet == null)
                {
                    _pagingSet = new ExtGridPagingSet(this);
                }
                return _pagingSet;
            }
            set { _pagingSet = value; }
        }

        [Category("Infolight")]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [NotifyParentProperty(true)]
        public ExtGridGridSet GridSet
        {
            get
            {
                if (_gridSet == null)
                {
                    _gridSet = new ExtGridGridSet(this);
                }
                return _gridSet;
            }
            set { _gridSet = value; }
        }

        [Category("Infolight")]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [TypeConverter(typeof(CollectionConverter))]
        [NotifyParentProperty(true)]
        public ExtGridColumnCollection Columns
        {
            get
            {
                if (_columns == null)
                    _columns = new ExtGridColumnCollection(this, typeof(ExtGridColumn));
                return _columns;
            }
        }

        [Category("Layout")]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        [NotifyParentProperty(true)]
        public ExtGridToolItemCollection ToolItems
        {
            get
            {
                if (_toolItems == null)
                {
                    _toolItems = new ExtGridToolItemCollection(this, typeof(ExtGridToolItem));

                    //ExtGridButtonToolItem itemRefresh = new ExtGridButtonToolItem();
                    //itemRefresh.Id = "btnRefresh";
                    //itemRefresh.Text = "refresh";
                    //itemRefresh.IconUrl = "~/ExtJs/resources/images/infolight/refresh.png";
                    //itemRefresh.SysHandlerType = ExtGridSystemHandler.Refresh;
                    //_toolItems.Add(itemRefresh);

                    //ExtGridSeparationToolItem itemSeparate1 = new ExtGridSeparationToolItem();
                    //_toolItems.Add(itemSeparate1);

                    //ExtGridButtonToolItem itemAdd = new ExtGridButtonToolItem();
                    //itemAdd.Id = "btnAdd";
                    //itemAdd.Text = "add";
                    //itemAdd.IconUrl = "~/ExtJs/resources/images/infolight/add.png";
                    //itemAdd.SysHandlerType = ExtGridSystemHandler.Add;
                    //_toolItems.Add(itemAdd);

                    //ExtGridButtonToolItem itemEdit = new ExtGridButtonToolItem();
                    //itemEdit.Id = "btnEdit";
                    //itemEdit.Text = "edit";
                    //itemEdit.IconUrl = "~/ExtJs/resources/images/infolight/edit.png";
                    //itemEdit.SysHandlerType = ExtGridSystemHandler.Edit;
                    //_toolItems.Add(itemEdit);

                    //ExtGridButtonToolItem itemDelete = new ExtGridButtonToolItem();
                    //itemDelete.Id = "btnDelete";
                    //itemDelete.Text = "delete";
                    //itemDelete.IconUrl = "~/ExtJs/resources/images/infolight/delete.png";
                    //itemDelete.SysHandlerType = ExtGridSystemHandler.Delete;
                    //_toolItems.Add(itemDelete);

                    //PropertyDescriptor propToolItems = TypeDescriptor.GetProperties(typeof(ExtGrid))["ToolItems"];
                    //propToolItems.SetValue(this, _toolItems);
                }
                return _toolItems;
            }
        }
        #endregion

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            if (!Page.IsPostBack)
            {
                this.RenderGrid(true);
            }
        }

        public string GenColumnsJsonArray()
        {
            ExtGridColumnCollection columns = this.Columns;
            if (columns.Count > 0)
            {
                StringBuilder JsonString = new StringBuilder();
                JsonString.Append("[");
                if (this.GenRowNumberer)
                {
                    JsonString.Append("new Ext.grid.RowNumberer(),");
                }
                for (int i = 0; i < columns.Count; i++)
                {
                    if (columns[i].Editor == ExtGridEditor.CheckBox && columns[i].FieldType == "boolean")
                    {
                        JsonString.Append("new Ext.grid.CheckColumn({");
                    }
                    else
                    {
                        JsonString.Append("{");
                    }

                    if (!string.IsNullOrEmpty(columns[i].ColumnName))
                    {
                        JsonString.AppendFormat("id:'{0}',", columns[i].ColumnName);
                    }
                    if (!string.IsNullOrEmpty(columns[i].HeaderText))
                    {
                        JsonString.AppendFormat("header:'{0}',", columns[i].HeaderText);
                    }
                    if (!string.IsNullOrEmpty(columns[i].DataField))
                    {
                        JsonString.AppendFormat("dataIndex:'{0}',", columns[i].DataField);
                    }
                    if (!string.IsNullOrEmpty(columns[i].TextAlign) && columns[i].TextAlign != "left")
                    {
                        JsonString.AppendFormat("align:'{0}',", columns[i].TextAlign);
                    }
                    if (!string.IsNullOrEmpty(columns[i].Formatter))
                    {
                        if (columns[i].Editor == ExtGridEditor.DateTimePicker)
                        {
                            // renderer控制顯示在grid-cell內日期的格式
                            JsonString.AppendFormat("renderer:Ext.util.Format.dateRenderer('{0}'),", columns[i].Formatter);
                        }
                        else
                        {
                            JsonString.AppendFormat("renderer:{0},", columns[i].Formatter);
                        }
                    }
                    if (!columns[i].Visible)
                    {
                        JsonString.Append("hidden:false,");
                    }
                    if (columns[i].AllowSort)
                    {
                        JsonString.Append("sortable:true,");
                    }
                    if (!columns[i].Resizable)
                    {
                        JsonString.Append("resizable:false,");
                    }
                    if (columns[i].Editor == ExtGridEditor.CheckBox && columns[i].FieldType == "boolean")
                    {
                        JsonString.AppendFormat("width:{0}}}),", columns[i].Width.ToString());
                    }
                    else
                    {
                        string valiConfig = this.GenValidateConfig(columns[i]);
                        switch (columns[i].Editor)
                        {
                            case ExtGridEditor.TextBox:
                                JsonString.AppendFormat("editor:new Ext.form.TextField({0}),", string.IsNullOrEmpty(valiConfig) ? "" : ("{" + valiConfig + "}"));
                                break;
                            case ExtGridEditor.DateTimePicker:
                                // format控制datepicker內日期的格式
                                if (string.IsNullOrEmpty(valiConfig))
                                {
                                    JsonString.AppendFormat("editor:new Ext.form.DateField({{format:'{0}'}}),", columns[i].Formatter);
                                }
                                else
                                {
                                    JsonString.AppendFormat("editor:new Ext.form.DateField({{format:'{0}',{1}}}),", columns[i].Formatter, valiConfig);
                                }
                                break;
                            case ExtGridEditor.ComboBox:
                                if (!string.IsNullOrEmpty(columns[i].EditControlId))
                                {
                                    object ocmb = this.GetObjByID(columns[i].EditControlId);
                                    if (ocmb != null && ocmb is ExtComboBox)
                                    {
                                        ExtComboBox cmb = ocmb as ExtComboBox;
                                        //JsonString.AppendFormat("editor:{0},", cmb.GenComboBoxConfig(valiConfig));
                                        JsonString.AppendFormat("editor:new Ext.grid.GridEditor(new Ext.form.ComboBox({0})),", cmb.GenComboBoxConfig(valiConfig));
                                    }
                                }
                                break;
                        }
                        JsonString.AppendFormat("width:{0}}},", columns[i].Width.ToString());
                    }
                }
                if (JsonString.ToString().EndsWith(","))
                {
                    JsonString.Remove(JsonString.Length - 1, 1);
                }
                JsonString.Append("]");
                return JsonString.ToString();
            }
            return "";
        }

        public string GenFieldsJsonArray()
        {
            ExtGridColumnCollection columns = this.Columns;
            if (columns.Count > 0)
            {
                StringBuilder JsonString = new StringBuilder();
                JsonString.Append("[");
                for (int i = 0; i < columns.Count; i++)
                {
                    if (!string.IsNullOrEmpty(columns[i].DataField))
                    {
                        JsonString.Append("{");
                        JsonString.AppendFormat("name:'{0}'", columns[i].DataField);
                        if (!string.IsNullOrEmpty(columns[i].FieldType) && columns[i].FieldType != "string")
                        {
                            JsonString.AppendFormat(",type:'{0}'", columns[i].FieldType);
                        }
                        if (i == columns.Count - 1)
                        {
                            JsonString.Append("}");
                        }
                        else
                        {
                            JsonString.Append("},");
                        }
                    }
                }
                JsonString.Append("]");
                return JsonString.ToString();
            }
            return "";
        }

        public string GenToolItemsJsonArray()
        {
            StringBuilder jsonString = new StringBuilder();
            if (this.ToolItems.Count > 0)
            {
                string[] toolTexts = SysMsg.GetSystemMessage(CliUtils.fClientLang, "AjaxTools", "ExtGrid", "ToolItems", true).Split(',');
                jsonString.Append("[");
                for (int i = 0; i < this.ToolItems.Count; i++)
                {
                    switch (this.ToolItems[i].ToolItemType)
                    {
                        case ExtGridToolItemType.Button:
                            jsonString.Append("{");
                            if (!string.IsNullOrEmpty(this.ToolItems[i].ButtonName))
                            {
                                jsonString.AppendFormat("id:'{0}',", this.ToolItems[i].ButtonName);
                            }
                            if (!string.IsNullOrEmpty(this.ToolItems[i].Text))
                            {
                                string text = this.ToolItems[i].Text;
                                if (this.GetServerText)
                                {
                                    switch (this.ToolItems[i].ButtonName)
                                    {
                                        case "btnAdd":
                                            text = toolTexts[0];
                                            break;
                                        case "btnEdit":
                                            text = toolTexts[1];
                                            break;
                                        case "btnDelete":
                                            text = toolTexts[2];
                                            break;
                                        case "btnSave":
                                            text = toolTexts[3];
                                            break;
                                        case "btnAbort":
                                            text = toolTexts[4];
                                            break;
                                        case "btnQuery":
                                            text = toolTexts[6];
                                            break;
                                        case "btnRefresh":
                                            text = toolTexts[5];
                                            break;
                                    }
                                }
                                jsonString.AppendFormat("text:'{0}',", text);
                            }
                            if (!string.IsNullOrEmpty(this.ToolItems[i].IconUrl))
                            {
                                jsonString.AppendFormat("icon:'{0}',", this.ResolveClientUrl(this.ToolItems[i].IconUrl));
                            }
                            if (!string.IsNullOrEmpty(this.ToolItems[i].CssClass))
                            {
                                jsonString.AppendFormat("cls:'{0}',", this.ToolItems[i].CssClass);
                            }
                            if (!string.IsNullOrEmpty(this.ToolItems[i].Handler))
                            {
                                jsonString.AppendFormat("handler:{0}", this.ToolItems[i].Handler);
                            }
                            else
                            {
                                jsonString.Append("handler:function(sender, args){");
                                switch (this.ToolItems[i].SysHandlerType)
                                {
                                    case ExtGridSystemHandler.Add:
                                        object o = this.GetObjByID(this.DataSourceID);
                                        if (o != null && o is WebDataSource)
                                        {
                                            WebDataSource wds = o as WebDataSource;
                                            DataTable tab = wds.InnerDataSet.Tables[wds.DataMember];
                                            string defaultValues = this.GenDefaultValues(wds);

                                            if (string.IsNullOrEmpty(this.EditPanelID))
                                            {
                                                jsonString.AppendFormat("addGridRecord('{0}',{1});", this.ID, string.IsNullOrEmpty(defaultValues) ? "{}" : defaultValues);
                                            }
                                            else
                                            {
                                                UpdatePanel upan = this.GetModalUpdatePanel(1);
                                                if (upan != null)
                                                {
                                                    //jsonString.AppendFormat("addGridRecordModal('{0}', '{1}');", upan.UniqueID, this.EditPanelID);
                                                    jsonString.AppendFormat("addGridRecordModal('{0}');", upan.UniqueID);
                                                }
                                            }
                                        }
                                        break;
                                    case ExtGridSystemHandler.Edit:
                                        if (string.IsNullOrEmpty(this.EditPanelID))
                                        {
                                            jsonString.AppendFormat("editGridRecord('{0}', '{1}');", 
                                                this.ID,
                                                SysMsg.GetSystemMessage(CliUtils.fClientLang, "AjaxTools", "ExtGrid", "NonSelectToEdit", true));
                                        }
                                        else
                                        {
                                            UpdatePanel upan = this.GetModalUpdatePanel(1);
                                            if (upan != null)
                                            {
                                                jsonString.AppendFormat("editGridRecordModal('{0}', '{1}', {2}, '{3}');", 
                                                    this.ID, 
                                                    upan.UniqueID, 
                                                    GenKeyFieldsArray(),
                                                    SysMsg.GetSystemMessage(CliUtils.fClientLang, "AjaxTools", "ExtGrid", "NonSelectToEdit", true));
                                            }
                                        }
                                        break;
                                    case ExtGridSystemHandler.Delete:
                                        jsonString.Append("var source = null;");
                                        o = this.GetObjByID(this.DataSourceID);
                                        if (o != null && o is WebDataSource)
                                        {
                                            WebDataSource wds = o as WebDataSource;
                                            if (wds.AutoApply)
                                            {
                                                string remoteName = wds.RemoteName;
                                                if (!string.IsNullOrEmpty(remoteName) && remoteName.IndexOf('.') != -1)
                                                {
                                                    jsonString.AppendFormat("source={{url:'{0}'}};",
                                                        this.ResolveClientUrl(this.StoreSet.ServiceUrl));
                                                }
                                            }
                                        }
                                        jsonString.AppendFormat("deleteGridRecord('{0}', {1}, '{2}', '{3}', source);", 
                                            this.ID, 
                                            this.GenKeyFieldsArray(),
                                            SysMsg.GetSystemMessage(CliUtils.fClientLang, "AjaxTools", "ExtGrid", "SureDelete", true),
                                            SysMsg.GetSystemMessage(CliUtils.fClientLang, "AjaxTools", "ExtGrid", "NonSelectToDelete", true));
                                        break;
                                    case ExtGridSystemHandler.Refresh:
                                        jsonString.AppendFormat("refreshGrid('{0}');", this.ID);
                                        break;
                                    case ExtGridSystemHandler.Save:
                                        o = this.GetObjByID(this.DataSourceID);
                                        if (o != null && o is WebDataSource)
                                        {
                                            WebDataSource wds = o as WebDataSource;
                                            string remoteName = wds.RemoteName;
                                            if (!string.IsNullOrEmpty(remoteName) && remoteName.IndexOf('.') != -1)
                                            {
                                                jsonString.AppendFormat("var source={{url:'{0}',keys:{1}}};saveGridRecords('{2}', source, true);",
                                                    this.ResolveClientUrl(this.StoreSet.ServiceUrl),
                                                    this.GenKeyFieldsArray(),
                                                    this.ID);
                                            }
                                        }
                                        break;
                                    case ExtGridSystemHandler.Abort:
                                        jsonString.AppendFormat("abortGridRecords('{0}');", this.ID);
                                        break;
                                    case ExtGridSystemHandler.Query:
                                        if (!string.IsNullOrEmpty(this.QueryPanelID))
                                        {
                                            UpdatePanel upan = this.GetModalUpdatePanel(2);
                                            if (upan != null)
                                            {
                                                jsonString.AppendFormat("__doPostBack('{0}');",
                                                    upan.UniqueID);
                                            }
                                        }
                                        break;
                                }
                                jsonString.Append("}");
                            }
                            jsonString.Append("}");
                            break;
                        case ExtGridToolItemType.Label:
                            jsonString.AppendFormat("'{0}'", this.ToolItems[i].Text);
                            break;
                        case ExtGridToolItemType.Separation:
                            jsonString.AppendFormat("'-'");
                            break;
                        case ExtGridToolItemType.Fill:
                            jsonString.AppendFormat("'->'");
                            break;
                    }
                    if (i < this.ToolItems.Count - 1)
                    {
                        jsonString.Append(",");
                    }
                }
                jsonString.Append("]");
            }
            return jsonString.ToString();
        }

        public string GenValidjsonArray()
        {
            StringBuilder builder = new StringBuilder();
            foreach (ExtGridColumn column in this.Columns)
            {
                string validConfig = GenValidateConfig(column);
                if (!string.IsNullOrEmpty(validConfig))
                {
                    builder.AppendFormat("{{ field: '{0}', validConfig: {{ {1} }} }},", column.DataField, validConfig);
                }
            }
            if (builder.ToString().EndsWith(","))
            {
                builder.Remove(builder.Length - 1, 1);
            }
            return builder.ToString();
        }

        public string GenStoreConfigJsonObject()
        {
            StringBuilder jsonString = new StringBuilder();
            jsonString.Append("{");
            if (!string.IsNullOrEmpty(this.StoreSet.ServiceUrl))
            {
                jsonString.AppendFormat("proxy:new Ext.data.HttpProxy({{url: '{0}?oper=select'}}),", this.ResolveClientUrl(this.StoreSet.ServiceUrl));
            }
            jsonString.Append("baseParams:{");
            if (this.Columns.Count > 0)
            {
                jsonString.Append("fields:'");
                for (int i = 0; i < this.Columns.Count; i++)
                {
                    if (i < this.Columns.Count - 1)
                    {
                        jsonString.Append(this.Columns[i].DataField + ",");
                    }
                    else
                    {
                        jsonString.Append(this.Columns[i].DataField + "'");
                    }
                }
            }
            object o = this.GetObjByID(this.DataSourceID);
            if (o != null && o is WebDataSource)
            {
                WebDataSource wds = o as WebDataSource;
                string remoteName = wds.RemoteName;
                if (!string.IsNullOrEmpty(remoteName) && remoteName.IndexOf('.') != -1)
                {
                    if (jsonString.ToString().EndsWith("'"))
                    {
                        jsonString.Append(",");
                    }
                    jsonString.AppendFormat("module:'{0}',command:'{1}',sevmod:{2},", remoteName.Split('.')[0], wds.DataMember, wds.ServerModify.ToString().ToLower());
                    if (string.IsNullOrEmpty(wds.MasterDataSource))
                    {
                        jsonString.AppendFormat("cacheDataSet:'{0}',isDetails:'false',", this.Page.AppRelativeVirtualPath + this.DataSourceID);
                        if (!string.IsNullOrEmpty(wds.WhereStr))
                        {
                            jsonString.AppendFormat("where:'{0}'", GloFix.FormatESC(wds.WhereStr));
                        }
                    }
                    else
                    {
                        jsonString.AppendFormat("cacheDataSet:'{0}',isDetails:'true',", this.Page.AppRelativeVirtualPath + wds.MasterDataSource);
                        if (wds.RelationValues.Count > 0)
                        {
                            jsonString.AppendFormat("where:'{0}'", GloFix.FormatESC(GloFix.GetWhereString(wds.InnerDataSet.Tables[wds.DataMember], wds.RelationValues, "=", " AND ")));
                        }
                    }
                    if (jsonString.ToString().EndsWith(","))
                    {
                        jsonString.Remove(jsonString.Length - 1, 1);
                    }
                }
            }
            jsonString.Append("}}");
            return jsonString.ToString();
        }

        public string GenPageConfigJsonObject()
        {
            StringBuilder jsonString = new StringBuilder();
            if (this.PagingSet.AllowPage)
            {
                jsonString.Append("{");
                jsonString.AppendFormat("displayInfo:{0},emptyMsg:'{1}',displayMsg:'{2}',pageSize:{3}",
                    this.PagingSet.DisplayPageInfo.ToString().ToLower(),
                    SysMsg.GetSystemMessage(CliUtils.fClientLang, "AjaxTools", "ExtGrid", "EmptyMsg", true),
                    SysMsg.GetSystemMessage(CliUtils.fClientLang, "AjaxTools", "ExtGrid", "DisplayMsg", true),
                    this.getPageSize());
                jsonString.Append("}");
            }
            return jsonString.ToString();
        }

        public string GenGridConfigJsonObject()
        {
            StringBuilder jsonString = new StringBuilder();
            jsonString.Append("{");
            if (string.IsNullOrEmpty(this.GridSet.GridPanel))
            {
                jsonString.Append("renderTo:document.body,");
            }
            else
            {
                jsonString.AppendFormat("renderTo:'{0}',", this.GridSet.GridPanel);
            }

            jsonString.AppendFormat("id:'{0}',stripeRows:{1},collapsible:{2},autoExpandColumn:'{3}',width:{4},height:{5},title:'{6}',loadMask:{7},clicksToEdit:{8},layout:'fit',border:true,sm:new Ext.grid.RowSelectionModel({{singleSelect: true}})}}",
                this.ID,
                this.GridSet.AlternateRow.ToString().ToLower(),
                this.GridSet.GridCollapsible.ToString().ToLower(),
                this.GridSet.AutoFillingColumn,
                this.GridSet.Width,
                this.GridSet.Height,
                this.GridSet.Title,
                this.GridSet.LoadMask.ToString().ToLower(),
                this.GridSet.ClicksToEdit);

            return jsonString.ToString();
        }

        public string GenExpandRowTemplateHtml()
        {
            if (this.AllowExpandRow)
            {
                if (!string.IsNullOrEmpty(this.ExpanderRowTemplateHtml))
                {
                    return this.ExpanderRowTemplateHtml;
                }
                if (this.Columns.Count > 0)
                {
                    List<ExtGridColumn> expandColumnList = new List<ExtGridColumn>();
                    foreach (ExtGridColumn column in this.Columns)
                    {
                        if (column.ExpandColumn)
                        {
                            expandColumnList.Add(column);
                        }
                    }
                    int maxOneLine = 1, oneLine = 1;
                    foreach (ExtGridColumn column in expandColumnList)
                    {
                        if (column.NewLine)
                        {
                            maxOneLine = Math.Max(maxOneLine, oneLine);
                            oneLine = 1;
                        }
                        else
                        {
                            oneLine++;
                        }
                    }
                    maxOneLine = Math.Max(maxOneLine, oneLine);

                    StringBuilder builder = new StringBuilder();
                    builder.Append("<table class=\\'quid_grid_expandtab\\' cellspacing=\\'1\\'>");

                    int j = 1;
                    int percentWidth = 100 / maxOneLine;
                    for (int i = 0; i < expandColumnList.Count; i++)
                    {
                        string columnHtml = "";
                        ExtGridColumn col = expandColumnList[i];
                        ExtGridColumn nextCol = (i < expandColumnList.Count - 1) ? expandColumnList[i + 1] : null;

                        if (col.NewLine)
                        {
                            if (i != 0)
                            {
                                columnHtml += "</tr>";
                            }
                            columnHtml += "<tr>";
                        }

                        string styleWidth = "";
                        if (this.GridSet.ExpandColumnWidth > 0)
                        {
                            styleWidth = string.Format(" style=\\'width:{0}px\\'", this.GridSet.ExpandColumnWidth);
                        }

                        if (nextCol != null)
                        {
                            if (nextCol.NewLine)
                            {
                                if ((2 * (maxOneLine - j) + 1) > 1)
                                {

                                    columnHtml += "<td nowrap class=\\'quid_grid_nowarptd\\'" + styleWidth + "><b>{0}:</b></td><td class=\\'quid_grid_contenttd\\' colspan=\\'" + (2 * (maxOneLine - j) + 1).ToString() + "\\'>{{{1}}}</td>";
                                }
                                else
                                {
                                    columnHtml += "<td nowrap class=\\'quid_grid_nowarptd\\'" + styleWidth + "><b>{0}:</b></td><td class=\\'quid_grid_contenttd\\'>{{{1}}}</td>";
                                }
                                j = 1;
                            }
                            else
                            {
                                columnHtml += "<td nowrap class=\\'quid_grid_nowarptd\\'" + styleWidth + "><b>{0}:</b></td><td class=\\'quid_grid_contenttd\\'>{{{1}}}</td>";
                                j++;
                            }
                        }
                        else
                        {
                            if ((2 * (maxOneLine - j) + 1) > 1)
                            {
                                columnHtml += "<td nowrap class=\\'quid_grid_nowarptd\\'" + styleWidth + "><b>{0}:</b></td><td class=\\'quid_grid_contenttd\\' colspan=\\'" + (2 * (maxOneLine - j) + 1).ToString() + "\\'>{{{1}}}</td></tr>";
                            }
                            else
                            {
                                columnHtml += "<td nowrap class=\\'quid_grid_nowarptd\\'" + styleWidth + "><b>{0}:</b></td><td class=\\'quid_grid_contenttd\\'>{{{1}}}</td></tr>";
                            }
                        }
                        builder.AppendFormat(columnHtml, col.HeaderText, col.DataField);
                    }
                    builder.Append("</table>");
                    return builder.ToString();
                }
            }
            return "";
        }

        public string GenKeyFieldsArray()
        {
            ExtGridColumnCollection columns = this.Columns;
            StringBuilder builder = new StringBuilder();
            builder.Append("[");
            if (columns.Count > 0)
            {
                for (int i = 0; i < columns.Count; i++)
                {
                    if (columns[i].IsKeyField)
                    {
                        builder.AppendFormat("'{0}',", columns[i].DataField);
                    }
                }
                if (builder.ToString().EndsWith(","))
                {
                    builder.Remove(builder.Length - 1, 1);
                }
            }
            builder.Append("]");

            return builder.ToString();
        }

        public void RenderGrid(bool isRegisterToUpdatePanel)
        {
            object o = this.GetObjByID(this.DataSourceID);
            if (o != null && o is WebDataSource)
            {
                WebDataSource wds = o as WebDataSource;
                DataTable tab = wds.InnerDataSet.Tables[0];

                string fields = this.GenFieldsJsonArray();
                string columns = this.GenColumnsJsonArray();
                string tools = this.GenToolItemsJsonArray();
                string valids = this.GenValidjsonArray();
                string source = this.GenSvcSource();
                if (!string.IsNullOrEmpty(fields) && !string.IsNullOrEmpty(columns))
                {
                    string expandRowHtml = this.GenExpandRowTemplateHtml();
                    string pageConfig = this.GenPageConfigJsonObject();
                    string renderScript = string.Format("var {0}Config = {{fields:{1},columns:{2},{3}allowPage:{4},{5}{6}{7}{8}deletedItems:[],validArray:[{9}],storeConfig:{10},{11}gridConfig:{12}}};Ext.onReady(renderGrid, {0}Config);",
                        this.ID,
                        fields,
                        columns,
                        string.IsNullOrEmpty(tools) ? "" : string.Format("tools:{0},", tools),
                        this.PagingSet.AllowPage.ToString().ToLower(),
                        string.IsNullOrEmpty(expandRowHtml) ? "" : string.Format("expandRowTemplateHtml:'{0}',", expandRowHtml),
                        string.IsNullOrEmpty(this.EditPanelID) ? "" : string.Format("editPan:'{0}',", this.EditPanelID),
                        string.IsNullOrEmpty(this.QueryPanelID) ? "" : string.Format("queryPan:'{0}',", this.QueryPanelID),
                        string.IsNullOrEmpty(source) ? "" : string.Format("source:{{{0}}},", source),
                        valids,
                        this.GenStoreConfigJsonObject(),
                        string.IsNullOrEmpty(pageConfig) ? "" : string.Format("pageConfig:{0},", pageConfig),
                        this.GenGridConfigJsonObject());
                    if (isRegisterToUpdatePanel)
                    {
                        object scriptContainer = this.GetObjByID(this.GridSet.GridPanel);
                        if (scriptContainer != null && scriptContainer is UpdatePanel)
                        {
                            ScriptManager.RegisterStartupScript(scriptContainer as UpdatePanel, this.GetType(), Guid.NewGuid().ToString(), renderScript, true);
                            return;
                        }
                    }
                    this.Page.ClientScript.RegisterStartupScript(this.GetType(), Guid.NewGuid().ToString(), renderScript, true);
                }
            }
        }

        public string GenSvcSource()
        {
            StringBuilder builder = new StringBuilder();
            WebDataSource wds = this.GetObjByID(this.DataSourceID) as WebDataSource;
            if (wds != null)
            {
                if (wds.AutoApply)
                {
                    builder.AppendFormat("url:'{0}',keys:{1}",
                        this.ResolveClientUrl(this.StoreSet.ServiceUrl),
                        this.GenKeyFieldsArray());
                }
            }
            return builder.ToString();
        }

        public string GenDefaultValues(WebDataSource wds)
        {
            StringBuilder builder = new StringBuilder();
            builder.Append("{");
            DataTable tab = wds.InnerDataSet.Tables[wds.DataMember];
            foreach (ExtGridColumn column in this.Columns)
            {
                if (!string.IsNullOrEmpty(column.DefaultValue))
                {
                    if (column.DefaultValue.EndsWith("()"))
                    {
                        builder.AppendFormat("{0}:{1},", column.DataField, column.DefaultValue);
                    }
                    else
                    {
                        Type type = tab.Columns[column.DataField].DataType;
                        if (GloFix.IsNumeric(type))
                        {
                            builder.AppendFormat("{0}:{1},", column.DataField, column.DefaultValue);
                        }
                        else if (type == typeof(Boolean))
                        {
                            builder.AppendFormat("{0}:{1},", column.DataField, column.DefaultValue.ToLower());
                        }
                        else
                        {
                            builder.AppendFormat("{0}:'{1}',", column.DataField, column.DefaultValue);
                        }
                    }
                }
            }
            if (builder.ToString().EndsWith(","))
            {
                builder.Remove(builder.Length - 1, 1);
            }
            if (!string.IsNullOrEmpty(wds.MasterDataSource))
            {
                builder.Append(GloFix.GetWhereString(tab, wds.RelationValues, ":", ","));
            }
            builder.Append("}");
            return builder.ToString();
        }

        public string GenValidateConfig(ExtGridColumn column)
        {
            StringBuilder builder = new StringBuilder();
            if (!column.AllowNull)
            {
                builder.Append("allowBlank:false,");
            }
            string message = "";
            switch (column.ValidType)
            { 
                case ValidateType.None:
                    break;
                case ValidateType.Alpha:
                    message = SysMsg.GetSystemMessage(CliUtils.fClientLang, "AjaxTools", "ExtGrid", "ValidAlphaMsg", true);
                    builder.AppendFormat("vtype:'alpha',alphaText:'{0}',", message);
                    break;
                case ValidateType.AlphaNumber:
                    message = SysMsg.GetSystemMessage(CliUtils.fClientLang, "AjaxTools", "ExtGrid", "ValidAlphaNumMsg", true);
                    builder.AppendFormat("vtype:'alphanum',alphanumText:'{0}',", message);
                    break;
                case ValidateType.Email:
                    message = SysMsg.GetSystemMessage(CliUtils.fClientLang, "AjaxTools", "ExtGrid", "ValidEmailMsg", true);
                    builder.AppendFormat("vtype:'email',emailText:'{0}',", message);
                    break;
                case ValidateType.Url:
                    message = SysMsg.GetSystemMessage(CliUtils.fClientLang, "AjaxTools", "ExtGrid", "ValidUrlMsg", true);
                    builder.AppendFormat("vtype:'url',urlText:'{0}',", message);
                    break;
                case ValidateType.Int:
                    message = SysMsg.GetSystemMessage(CliUtils.fClientLang, "AjaxTools", "ExtGrid", "ValidIntMsg", true);
                    builder.AppendFormat("vtype:'isint',invalidText:'{0}',", message);
                    break;
                case ValidateType.Float:
                    message = SysMsg.GetSystemMessage(CliUtils.fClientLang, "AjaxTools", "ExtGrid", "ValidFloatMsg", true);
                    builder.AppendFormat("vtype:'isfloat',invalidText:'{0}',", message);
                    break;
                case ValidateType.IPAddress:
                    message = SysMsg.GetSystemMessage(CliUtils.fClientLang, "AjaxTools", "ExtGrid", "ValidIPMsg", true);
                    builder.AppendFormat("vtype:'ip',invalidText:'{0}',", message);
                    break;
            }
            if (builder.ToString().EndsWith(","))
            {
                builder.Remove(builder.Length - 1, 1);
            }
            return builder.ToString();
        }

        int getPageSize()
        {
            object o = this.GetObjByID(this.DataSourceID);
            if (o != null && o is WebDataSource)
            {
                WebDataSource wds = o as WebDataSource;
                return wds.PacketRecords;
            }
            return -1;
        }

        public void SetEditMode()
        {
            if (this.Page.Request.Form["__EVENTARGUMENT"] != null)
            {
                UpdatePanel upan = this.GetModalUpdatePanel(1);
                if (upan != null && this.Page.Request.Form["__EVENTTARGET"] == upan.UniqueID)
                {
                    JavaScriptSerializer serializer = new JavaScriptSerializer();
                    object args = serializer.DeserializeObject(this.Page.Request.Form["__EVENTARGUMENT"]);
                    if (args != null)
                    {
                        Dictionary<string, object> dicArgs = args as Dictionary<string, object>;
                        CompositeDataBoundControl view = this.GetEditView();
                        if (view != null)
                        {
                            this.ChangeEditViewMode(view, dicArgs);
                        }
                    }
                }
            }
        }

        public void SetQueryState(WebClientQuery qry, Panel pan)
        {
            UpdatePanel upan = this.GetModalUpdatePanel(2);
            if (upan != null && this.Page.Request.Form["__EVENTTARGET"] == upan.UniqueID)
            {
                //qry.Clear(pan);
                string script = string.Format("var behavior=$find('{0}behavior');if(behavior){{behavior.show();}}", this.QueryPanelID);
                ScriptManager.RegisterStartupScript(upan, this.GetType(), Guid.NewGuid().ToString(), script, true);
            }
        }

        public void Submit(CompositeDataBoundControl view)
        {
            object o = this.GetObjByID(this.DataSourceID);
            if (o != null && o is WebDataSource)
            {
                WebDataSource wds = o as WebDataSource;
                string loadType = "";
                //int position = -1;
                if (view is DetailsView)
                {
                    WebDetailsView detView = view as WebDetailsView;
                    if (detView.CurrentMode == DetailsViewMode.Insert)
                    {
                        detView.InsertItem(false);
                        loadType = "insert";
                        //position = wds.InnerDataSet.Tables[wds.DataMember].Rows.Count - 1;
                    }
                    else if (detView.CurrentMode == DetailsViewMode.Edit)
                    {
                        detView.UpdateItem(false);
                        loadType = "edit";
                    }
                    WebValidate validate = (WebValidate)detView.ExtendedFindChildControl(this.DataSourceID, FindControlType.DataSourceID, typeof(WebValidate));
                    if (validate != null && detView.ValidateFailed)
                    {
                        return;
                    }
                }
                else if (view is FormView)
                {
                    WebFormView fmView = view as WebFormView;
                    if (fmView.CurrentMode == FormViewMode.Insert)
                    {
                        fmView.InsertItem(false);
                        loadType = "insert";
                        //position = wds.InnerDataSet.Tables[wds.DataMember].Rows.Count - 1;
                    }
                    else if (fmView.CurrentMode == FormViewMode.Edit)
                    {
                        fmView.UpdateItem(false);
                        loadType = "edit";
                    }
                    WebValidate validate = (WebValidate)fmView.ExtendedFindChildControl(this.DataSourceID, FindControlType.DataSourceID, typeof(WebValidate));
                    if (validate != null && fmView.ValidateFailed)
                    {
                        return;
                    }
                }

                StringBuilder builder = new StringBuilder();
                if (wds.AutoApply)
                {
                    builder.AppendFormat("var grid=Ext.getCmp('{0}');", this.ID);
                    builder.Append("grid.store.reload();");
                }
                else
                {
                    DataTable tab = wds.InnerDataSet.Tables[wds.DataMember].GetChanges();
                    if (tab != null && tab.Rows.Count == 1)
                    {
                        builder.AppendFormat("var grid=Ext.getCmp('{0}');", this.ID);
                        DataRow changedRow = tab.Rows[0];
                        if (loadType == "insert")
                        {
                            builder.Append("var changedRecord={");
                            foreach (DataColumn column in tab.Columns)
                            {
                                if (changedRow[column] != DBNull.Value)
                                {
                                    Type type = column.DataType;
                                    if (GloFix.IsNumeric(type))
                                    {
                                        builder.AppendFormat("{0}:{1},", column.ColumnName, changedRow[column.ColumnName]);
                                    }
                                    else if (type == typeof(bool))
                                    {
                                        builder.AppendFormat("{0}:{1},", column.ColumnName, changedRow[column.ColumnName].ToString().ToLower());
                                    }
                                    else
                                    {
                                        builder.AppendFormat("{0}:'{1}',", column.ColumnName, changedRow[column.ColumnName]);
                                    }
                                }
                            }
                            if (builder.ToString().EndsWith(","))
                            {
                                builder.Remove(builder.Length - 1, 1);
                            }
                            builder.Append("};");
                            builder.AppendFormat("insertStore('{0}',changedRecord);", this.ID);
                        }
                        else if (loadType == "edit")
                        {
                            builder.Append("var recordKeys={");
                            foreach (ExtGridColumn extColumn in this.Columns)
                            {
                                if (extColumn.IsKeyField)
                                {
                                    Type type = tab.Columns[extColumn.DataField].DataType;
                                    if (GloFix.IsNumeric(type))
                                    {
                                        builder.AppendFormat("{0}:{1},", extColumn.DataField, changedRow[extColumn.DataField]);
                                    }
                                    else if (type == typeof(bool))
                                    {
                                        builder.AppendFormat("{0}:{1},", extColumn.DataField, changedRow[extColumn.DataField].ToString().ToLower());
                                    }
                                    else
                                    {
                                        builder.AppendFormat("{0}:'{1}',", extColumn.DataField, changedRow[extColumn.DataField]);
                                    }
                                }
                            }
                            if (builder.ToString().EndsWith(","))
                            {
                                builder.Remove(builder.Length - 1, 1);
                            }
                            builder.Append("};");

                            builder.Append("var changedRecord={");
                            foreach (DataColumn column in tab.Columns)
                            {
                                if (!changedRow[column, DataRowVersion.Current].Equals(changedRow[column, DataRowVersion.Original]))
                                {
                                    Type type = column.DataType;
                                    if (GloFix.IsNumeric(type))
                                    {
                                        builder.AppendFormat("{0}:{1},", column.ColumnName, changedRow[column.ColumnName]);
                                    }
                                    else if (type == typeof(bool))
                                    {
                                        builder.AppendFormat("{0}:{1},", column.ColumnName, changedRow[column.ColumnName].ToString().ToLower());
                                    }
                                    else
                                    {
                                        builder.AppendFormat("{0}:'{1}',", column.ColumnName, changedRow[column.ColumnName]);
                                    }
                                }
                            }
                            if (builder.ToString().EndsWith(","))
                            {
                                builder.Remove(builder.Length - 1, 1);
                            }
                            builder.Append("};");
                            builder.Append("updateStore(grid.store,recordKeys,changedRecord);");
                        }
                        wds.InnerDataSet.Tables[wds.DataMember].AcceptChanges();
                    }
                }

                UpdatePanel upan = this.GetModalUpdatePanel(1);
                if (upan != null)
                {
                    builder.AppendFormat("var behavior=$find('{0}behavior');", this.EditPanelID);
                    builder.Append("if(behavior){behavior.hide();}");
                    if (loadType == "insert")
                    {
                        builder.AppendFormat("locateAfterInsertRecord(grid);");
                    }
                }
                if (builder.Length > 0)
                {
                    ScriptManager.RegisterStartupScript(upan, this.GetType(), Guid.NewGuid().ToString(), builder.ToString(), true);
                }
            }
        }

        public void Cancel()
        {
            CompositeDataBoundControl view = this.GetEditView();
            if (view != null)
            {
                Dictionary<string, object> dicArgs = new Dictionary<string, object>();
                dicArgs.Add("mode", "readonly");
                this.ChangeEditViewMode(view, dicArgs);
            }
        }

        public void Query(WebClientQuery qry, Panel pan)
        {
            UpdatePanel upan = this.GetModalUpdatePanel(2);
            if (upan != null)
            {
                qry.Execute(pan);
                WebDataSource wds = this.GetObjByID(qry.DataSourceID) as WebDataSource;
                if (wds != null)
                {
                    StringBuilder builder = new StringBuilder();
                    builder.AppendFormat("var behavior=$find('{0}behavior');", this.QueryPanelID);
                    builder.Append("if(behavior){behavior.hide();}");


                    builder.AppendFormat("setWhere('{0}','{1}',{2});", 
                        this.ID, 
                        wds.WhereStr.Trim().Replace("'", "\\'"),
                        wds.PacketRecords);
                    ScriptManager.RegisterStartupScript(upan, this.GetType(), Guid.NewGuid().ToString(), builder.ToString(), true);
                }
            }
        }

        ExtModalPanel GetModalPanel(int modalPanelType)
        {
            string panel = "";
            switch (modalPanelType)
            {
                case 1:
                    panel = this.EditPanelID;
                    break;
                case 2:
                    panel = this.QueryPanelID;
                    break;
            }
            object o = this.GetObjByID(panel);
            if (o != null && o is ExtModalPanel)
            {
                return (ExtModalPanel)o;
            }
            return null;
        }

        UpdatePanel GetModalUpdatePanel(int modaltype)
        {
            ExtModalPanel pan = this.GetModalPanel(modaltype);
            if (pan != null)
            {
                foreach (Control ctrl in pan.Controls)
                {
                    if (ctrl is UpdatePanel)
                    {
                        return (UpdatePanel)ctrl;
                    }
                }
            }
            return null;
        }

        CompositeDataBoundControl GetEditView()
        {
            UpdatePanel upan = this.GetModalUpdatePanel(1);
            if (upan != null)
            {
                foreach (Control ctrl in upan.ContentTemplateContainer.Controls)
                {
                    if (ctrl is FormView || ctrl is DetailsView)
                    {
                        return ctrl as CompositeDataBoundControl;
                    }
                }
            }
            return null;
        }

        void ChangeEditViewMode(CompositeDataBoundControl view, Dictionary<string, object> dicArgs)
        {
            string mode = dicArgs["mode"] as string;
            if (!string.IsNullOrEmpty(mode))
            {
                object o = this.GetObjByID(this.DataSourceID);
                if (o != null && o is WebDataSource)
                {
                    WebDataSource wds = ((WebDataSource)o);
                    if (mode == "insert")
                    {
                        #region insert
                        if (view is DetailsView)
                        {
                            DetailsView detView = view as DetailsView;
                            if (detView.CurrentMode != DetailsViewMode.Insert)
                            {
                                detView.ChangeMode(DetailsViewMode.Insert);
                            }
                        }
                        else if (view is FormView)
                        {
                            FormView fmView = view as FormView;
                            if (fmView.CurrentMode != FormViewMode.Insert)
                            {
                                fmView.ChangeMode(FormViewMode.Insert);
                            }
                        }
                        #endregion
                    }
                    else if (mode == "edit")
                    {
                        #region edit
                        List<object> lstKeys = new List<object>();
                        foreach (KeyValuePair<string, object> pair in dicArgs)
                        {
                            if (pair.Key != "mode")
                            {
                                lstKeys.Add(pair.Value);
                            }
                        }
                        int index = -1;
                        if (string.IsNullOrEmpty(wds.MasterDataSource))
                        {
                            if (string.IsNullOrEmpty(wds.View.Sort))
                            {
                                wds.View.ApplyDefaultSort = true;
                            }
                            index = wds.View.Find(lstKeys.ToArray());
                        }
                        else
                        {
                            DataTable detTab = wds.View.Table;
                            DataColumn[] keyColumns = detTab.PrimaryKey;
                            DataRow editRow = detTab.Rows.Find(lstKeys.ToArray());
                            for (int i = 0; i < detTab.Rows.Count; i++)
                            {
                                bool isEditRow = true;
                                foreach (DataColumn column in keyColumns)
                                {
                                    if (!editRow[column].Equals(detTab.Rows[i][column]))
                                    {
                                        isEditRow = false;
                                        break;
                                    }
                                }
                                if (isEditRow)
                                {
                                    index = i;
                                    break;
                                }
                            }
                        }

                        if (view is DetailsView)
                        {
                            DetailsView detView = view as DetailsView;
                            if (index != -1 && detView.CurrentMode != DetailsViewMode.Edit)
                            {
                                detView.PageIndex = index;
                                detView.DataBind();
                                detView.ChangeMode(DetailsViewMode.Edit);
                            }
                        }
                        else if (view is FormView)
                        {
                            FormView fmView = view as FormView;
                            if (index != -1 && fmView.CurrentMode != FormViewMode.Edit)
                            {
                                fmView.PageIndex = index;
                                fmView.DataBind();
                                fmView.ChangeMode(FormViewMode.Edit);
                            }
                        }
                        #endregion
                    }
                    else if (mode == "readonly")
                    {
                        #region readonly
                        if (view is DetailsView)
                        {
                            DetailsView detView = view as DetailsView;
                            if (detView.CurrentMode != DetailsViewMode.ReadOnly)
                            {
                                detView.ChangeMode(DetailsViewMode.ReadOnly);
                            }
                        }
                        else if (view is FormView)
                        {
                            FormView fmView = view as FormView;
                            if (fmView.CurrentMode != FormViewMode.ReadOnly)
                            {
                                fmView.ChangeMode(FormViewMode.ReadOnly);
                            }
                        }
                        #endregion
                    }
                }
                UpdatePanel upan = this.GetModalUpdatePanel(1);
                if (upan != null)
                {
                    string oper = "";
                    if(mode == "insert" || mode=="edit")
                    {
                        oper = "show";
                    }
                    else if(mode=="readonly")
                    {
                        oper = "hide";
                    }
                    string script = string.Format("var behavior=$find('{0}behavior');if(behavior){{behavior.{1}();}}", this.EditPanelID, oper);
                    ScriptManager.RegisterStartupScript(upan, this.GetType(), Guid.NewGuid().ToString(), script, true);
                }
            }
        }
    }

    [TypeConverter(typeof(ExpandableObjectConverter))]
    public class ExtGridPagingSet : IChildSet
    {
        public ExtGridPagingSet(AjaxGridView parent)
        {
            _ownerGrid = parent;
        }

        AjaxGridView _ownerGrid = null;
        bool _allowPage = true;
        bool _displayPageInfo = true;
        //string _emptyMessage = "there's no record!";
        //string _displayMessage = "display from {0} to {1}, total:{2}";

        [Browsable(false)]
        public AjaxGridView OwnerGrid
        {
            get { return _ownerGrid; }
        }

        [DefaultValue(true)]
        [NotifyParentProperty(true)]
        public bool AllowPage
        {
            get { return _allowPage; }
            set { _allowPage = value; }
        }

        [DefaultValue(true)]
        [NotifyParentProperty(true)]
        public bool DisplayPageInfo
        {
            get { return _displayPageInfo; }
            set { _displayPageInfo = value; }
        }

        //[DefaultValue("there's no record!")]
        //[NotifyParentProperty(true)]
        //public string EmptyMessage
        //{
        //    get { return _emptyMessage; }
        //    set { _emptyMessage = value; }
        //}

        //[DefaultValue("display from {0} to {1}, total:{2}")]
        //[NotifyParentProperty(true)]
        //public string DisplayMessage
        //{
        //    get { return _displayMessage; }
        //    set { _displayMessage = value; }
        //}
    }

    [TypeConverter(typeof(ExpandableObjectConverter))]
    public class ExtGridStoreSet : IChildSet
    {
        public ExtGridStoreSet(AjaxGridView parent)
        {
            _ownerGrid = parent;
        }

        AjaxGridView _ownerGrid;
        string _svcUrl = "~/ExtJs/infolight/ExtGetData.ashx";

        [Browsable(false)]
        public AjaxGridView OwnerGrid
        {
            get { return _ownerGrid; }
        }

        [DefaultValue("~/ExtJs/infolight/ExtGetData.ashx")]
        [NotifyParentProperty(true)]
        [Editor(typeof(UrlEditor), typeof(UITypeEditor))]
        public string ServiceUrl
        {
            get { return _svcUrl; }
            set { _svcUrl = value; }
        }
    }

    [TypeConverter(typeof(ExpandableObjectConverter))]
    public class ExtGridGridSet : IChildSet
    {
        public ExtGridGridSet(AjaxGridView parent)
        {
            _ownerGrid = parent;
        }

        AjaxGridView _ownerGrid;
        string _gridPanel = "";
        string _title = "";
        string _autoFillingColumn = "";

        int _clicksToEdit = 2;
        int _width = 600;
        int _height = 300;
        int _expandColumnWidth = 0;

        bool _alternateRow = true;
        bool _gridCollapsible = true;
        bool _loadMask = true;

        [Browsable(false)]
        public AjaxGridView OwnerGrid
        {
            get { return _ownerGrid; }
        }

        [DefaultValue("")]
        [NotifyParentProperty(true)]
        [Editor(typeof(ExtStaticStringEditor), typeof(UITypeEditor))]
        public string GridPanel
        {
            get { return _gridPanel; }
            set { _gridPanel = value; }
        }

        [DefaultValue("")]
        [NotifyParentProperty(true)]
        public string Title
        {
            get { return _title; }
            set { _title = value; }
        }

        [DefaultValue("")]
        [NotifyParentProperty(true)]
        [Editor(typeof(ExtStaticStringEditor), typeof(UITypeEditor))]
        public string AutoFillingColumn
        {
            get { return _autoFillingColumn; }
            set { _autoFillingColumn = value; }
        }

        [DefaultValue(600)]
        [NotifyParentProperty(true)]
        public int Width
        {
            get { return _width; }
            set { _width = value; }
        }

        [DefaultValue(2)]
        [NotifyParentProperty(true)]
        public int ClicksToEdit
        {
            get { return _clicksToEdit; }
            set { _clicksToEdit = value; }
        }

        [DefaultValue(300)]
        [NotifyParentProperty(true)]
        public int Height
        {
            get { return _height; }
            set { _height = value; }
        }

        [DefaultValue(0)]
        [NotifyParentProperty(true)]
        public int ExpandColumnWidth
        {
            get { return _expandColumnWidth; }
            set { _expandColumnWidth = value; }
        }

        [DefaultValue(true)]
        [NotifyParentProperty(true)]
        public bool AlternateRow
        {
            get { return _alternateRow; }
            set { _alternateRow = value; }
        }

        [DefaultValue(true)]
        [NotifyParentProperty(true)]
        public bool GridCollapsible
        {
            get { return _gridCollapsible; }
            set { _gridCollapsible = value; }
        }

        [DefaultValue(true)]
        [NotifyParentProperty(true)]
        public bool LoadMask
        {
            get { return _loadMask; }
            set { _loadMask = value; }
        }
    }
}